import IEnumerator from "../interfaces/IEnumerator";
import TreeNode from "./TreeNode";

export default class NodeB2TEnumerator<T> implements IEnumerator<TreeNode<T>>{
    // 持有一个枚举器接口
    private _iter: IEnumerator<TreeNode<T>>;
    //声明一个数组对象
    private _arr !: Array<TreeNode<T> | undefined>;
    // 当前的数组索引
    private _arrIdx !: number;

    // 实现接口放current，用于返回当前正在枚举的节点TreeNode < T > | undefined
    public get current(): TreeNode<T> | undefined {
        // 数组越界检查
        if (this._arrIdx >= this._arr.length) {
            return undefined;
        } else {
            // 从数组中获取当前节点
            return this._arr[this._arrIdx];
        }
    }

    /**
     * 
     * @param iter { IEnumerator < TreeNode < T > > } 指向树结构的先根迭代器
     */
    public constructor(iter: IEnumerator<TreeNode<T>>) {
        // 指向先根迭代器
        this._iter = iter;
        // 调用reset，填充数组内容及_arrIdx
        this.reset();
    }

    /**
     * *实现接口方法，将枚举器设置为初始化状态，调用reset函数后，可以重用枚举器
     */
    public reset(): void {
        // 清空数组
        this._arr = [];
        // 调用先根枚举器，将结果全部存入数组
        while (this._iter.moveNext()) {
            this._arr.push(this._iter.current);
        }
        // 设置_arrIdx为数组的length
        // 因为后根遍历是先根遍历的逆操作，所以是从数组尾部向顶部的遍历
        this._arrIdx = this._arr.length;
    }

    /**
     * *实现接口函数moveNext，返回false，表示枚举结束，否则，返回true
     */
    public moveNext(): boolean {
        this._arrIdx--;
        return (this._arrIdx >= 0 && this._arrIdx < this._arr.length);
    }
}